package com.ruoyi.activity.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.activity.domain.*;
import com.ruoyi.activity.domain.Process;
import com.ruoyi.activity.dto.FlowApproveDto;
import com.ruoyi.activity.service.*;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessFlag;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import com.ruoyi.workflow.domain.Message;
import com.ruoyi.workflow.myenum.MessageType;
import com.ruoyi.workflow.service.UserMessageService;
import de.odysseus.el.ExpressionFactoryImpl;
import de.odysseus.el.util.SimpleContext;
import org.activiti.bpmn.model.*;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.ServerException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FlowServiceImpl implements IFlowService {

    @Resource
    private TaskService taskService;

    @Resource
    private RepositoryService repositoryService;

    @Resource
    private IActFunFormRelService actFunFormRelServiceImpl;

    @Autowired
    private IActHistoryTaskService actHistoryTaskServiceImpl;

    @Resource
    private ProcessEngineConfiguration configuration;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    protected ProcessEngine processEngine;

    @Resource
    private HistoryService historyService;

    @Autowired
    private IActTaskService actTaskService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IAssociationClapCulvertService associationClapCulvertServiceImpl;

    @Autowired
    private IWcPatentApplicationService wcPatentApplicationServiceImpl;

    @Autowired
    private IFyProjectApplyService fyProjectApplyService;

    @Autowired
    private IWcChangePatentApplicationService wcChangePatentApplicationService;
    @Autowired
    private IWcPatentApplicationService wcPatentApplicationService;

    @Autowired
    private IWcContentExamineService wcContentExamineService;

    @Resource
    private IActBusinessFlowRelService actBusinessFlowRelServiceImpl;

    @Resource
    private UserMessageService userMessageService;

    @Resource
    private IMessageInfoService messageInfoService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String start(Long businessId, String businessKey) throws Exception {

        // 根据业务标识查询流程
        ActFunFormRel actFunFormRel = actFunFormRelServiceImpl.getflowKeyByFunctionelKey(businessKey);
        if (actFunFormRel == null) {
            throw new ServerException("改功能未绑定流程，请联系管理员！");
        }
        LoginUser user = SecurityUtils.getLoginUser();
        SysUser loginUser = user.getUser();
        if(loginUser == null){
            throw new ServerException("请登录");
        }
        // 获取业务与流程关系
        ActBusinessFlowRel actBusinessFlowRel = actBusinessFlowRelServiceImpl.getOne(new LambdaQueryWrapper<ActBusinessFlowRel>()
                .eq(ActBusinessFlowRel::getBusinessId, businessId).eq(ActBusinessFlowRel::getBusinessType, businessKey));
        if(actBusinessFlowRel != null){
            // 退回后同意，撤回
            if(actBusinessFlowRel.getFlowState() != 4){
                throw new ServerException("当前数据已开始流程，请先审核");
            }
        } else {
            actBusinessFlowRel = new ActBusinessFlowRel();
        }

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
//        // 流程变量
//        HashMap<String, Object> variables = new HashMap<>();
//        variables.put("user", "admin");
        // 开启流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(actFunFormRel.getFlowKey(),actFunFormRel.getFlowName());
        Thread.sleep(1000);
        // 自动跳过第一个节点 提交节点
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        DescriptionInfo descriptionInfo = new DescriptionInfo();
        descriptionInfo.setRemarks("启动流程，" + task.getName());
        task.setDescription(JSON.toJSONString(descriptionInfo));
        task.setAssignee(loginUser.getUserId().toString());
        task.setOwner(loginUser.getUserId().toString());
        Map<String, Object> variabls = new HashMap<>();
//        variabls.put("approvalStatus", "approved");// 设置节点审核状态为通过
//        variabls.put("nodeToCompleteUserId",loginUser.getUserId());// 提交人
//        variabls.put("nodeToCompleteUserName",loginUser.getNickName());
//        variabls.put("outcome",outcome);
        taskService.saveTask(task);
        // 获取业务与流程关系

        List<UserTask> nextTaskNode = getNextTaskNode(task.getId(), null);
        if(!CollectionUtils.isEmpty(nextTaskNode)){
            UserTask userTask = nextTaskNode.get(0);
            String assignee = userTask.getAssignee();
            taskService.complete(task.getId(), variabls);

            // 给流程与业务关系下一节点审核人赋值
            if(StringUtils.isBlank(assignee)){
                throw new ServerException("请配置下一节点审核人");
            }
            actBusinessFlowRel.setProcHandlerId(userTask.getAssignee());
            Long assigneeLong = 0L;
            try {
                assigneeLong = Long.parseLong(assignee);
            } catch (Exception e){
                throw new ServerException("请配置下一节点审核人配置错误");
            }
            SysUser sysUser = sysUserService.selectUserById(assigneeLong);
            if(sysUser == null){
                throw new ServerException("下一节点审核人不存在");
            }
            actBusinessFlowRel.setProcHandlerName(sysUser.getNickName());
            actBusinessFlowRel.setTaskName(userTask.getName());

        } else {
            taskService.complete(task.getId());
        }
        // 维护业务数据
        updateBussiness(businessId,businessKey,processInstance.getId());

        // 保存流程与数据关系

        actBusinessFlowRel.setBusinessId(businessId.toString());
        actBusinessFlowRel.setBusinessType(businessKey);
        actBusinessFlowRel.setFlowKey(actFunFormRel.getFlowKey());
        actBusinessFlowRel.setFlowName(actFunFormRel.getFlowName());
        actBusinessFlowRel.setSendUserId(loginUser.getUserId().toString());
        actBusinessFlowRel.setSendUserName(loginUser.getNickName());
        actBusinessFlowRel.setSendDate(LocalDateTime.now());
        actBusinessFlowRel.setProcInstId(processInstance.getId());
        // 0未提交，1待审核，2已结束，3已驳回
        actBusinessFlowRel.setFlowState(1);
        actBusinessFlowRel.setCdate(LocalDateTime.now());
        actBusinessFlowRel.setMdate(LocalDateTime.now());
        actBusinessFlowRelServiceImpl.saveOrUpdate(actBusinessFlowRel);

        if(StringUtils.isNotBlank(actBusinessFlowRel.getProcHandlerId())){
            // 发送消息
            sendPcMessage(actBusinessFlowRel.getProcHandlerId(), businessKey, businessId);
        }
        updateBusinessByType(actBusinessFlowRel,actBusinessFlowRel.getFlowState().toString());
        return processInstance.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pass(FlowApproveDto flowApproveDto) throws ServerException {
        LoginUser user = SecurityUtils.getLoginUser();
        SysUser loginUser = user.getUser();
        Task currentTask = taskService.createTaskQuery().taskAssignee(loginUser.getUserId().toString()).processInstanceId(flowApproveDto.getFlowId()).singleResult();
        if(currentTask == null){
            throw new ServerException("当前流程节点不存在");
        }
        if(currentTask.getDelegationState() !=null && currentTask.getDelegationState().equals(DelegationState.PENDING)) {
            taskService.resolveTask(currentTask.getId());
        }
        String description = currentTask.getDescription();
        // 处理description
        if(StringUtils.isNotBlank(description)){
            DescriptionInfo descriptionInfo = JSON.parseObject(description, DescriptionInfo.class);
            descriptionInfo.setRemarks("审核通过：" + flowApproveDto.getDescription());
            if(flowApproveDto.getIsCountersign() != null && flowApproveDto.getIsCountersign() == 1){
                descriptionInfo.setApprovalStatus("指派专家");
            } else {
                descriptionInfo.setApprovalStatus("同意");
            }
            descriptionInfo.setApprovalFileIds(flowApproveDto.getApprovalFileUrls());
            currentTask.setDescription(JSON.toJSONString(descriptionInfo));
        }
        taskService.saveTask(currentTask);
        Map<String, Object> variabls = new HashMap<>();
        if(flowApproveDto.getIsCountersign() != null){
            variabls.put("countersign", flowApproveDto.getIsCountersign());
        }
//        variabls.put("approvalStatus", "approved");// 设置节点审核状态为通过
//        variabls.put("nodeToCompleteUserId",loginUser.getUserId());
//        variabls.put("nodeToCompleteUserName",loginUser.getNickName());
//        variabls.put("approvalFileIds", flowPassDto.getApprovalFileUrls());
//        variabls.put("outcome",outcome);
//        variabls.put("approvalFileIds", "111111111111");
//        Task task = taskService.createTaskQuery().taskAssignee(sysUser.getUserId().toString()).singleResult();
        // 获取业务与流程关系
        ActBusinessFlowRel actBusinessFlowRel = actBusinessFlowRelServiceImpl.getOne(new LambdaQueryWrapper<ActBusinessFlowRel>()
                .eq(ActBusinessFlowRel::getBusinessId, flowApproveDto.getBussinessId())
                .eq(ActBusinessFlowRel::getBusinessType, flowApproveDto.getBussinessType()));
        if(actBusinessFlowRel == null){
            throw new ServerException("业务数据与流程关系不存在");
        }
        List<UserTask> nextTaskNode = getNextTaskNode(currentTask.getId(), flowApproveDto.getIsCountersign());

        if(!CollectionUtils.isEmpty(nextTaskNode)){
            UserTask userTask = nextTaskNode.get(0);
            String assignee = userTask.getAssignee();
            // 如果是会签就设置会签用户
            if(flowApproveDto.getIsCountersign() != null && flowApproveDto.getIsCountersign() == 1){
                if(StringUtils.isNotBlank(flowApproveDto.getCountersignUserId())){
                    assignee = flowApproveDto.getCountersignUserId();
                    List<String> userList = new ArrayList<>();
                    Collections.addAll(userList, flowApproveDto.getCountersignUserId().split(","));
                    variabls.put("userList", userList);
                }
            }
            taskService.complete(currentTask.getId(), variabls);
            String procHandlerId = actBusinessFlowRel.getProcHandlerId();
            String[] split1 = procHandlerId.split(",");
            // 如果现在是会签流程
            if(split1.length != 1){
                String procHandlerName = actBusinessFlowRel.getProcHandlerName();
                List<String> ids = new ArrayList<>();
                for (String id : procHandlerId.split(",")) {
                    if(!id.equals(loginUser.getUserId().toString())){
                        ids.add(id);
                    }
                }
                List<String> names = new ArrayList<>();
                for (String name : procHandlerName.split(",")) {
                    if(!name.equals(loginUser.getNickName())){
                        names.add(name);
                    }
                }
                actBusinessFlowRel.setProcHandlerId(String.join(",",ids));
                actBusinessFlowRel.setProcHandlerName(String.join(",",names));
            } else {
                // 给流程与业务关系下一节点审核人赋值
                if(StringUtils.isBlank(assignee)){
                    throw new ServerException("请配置下一节点审核人");
                }
                actBusinessFlowRel.setProcHandlerId(assignee);
                List<String> assigneeNames = new ArrayList<>();
                try {
                    String[] split = assignee.split(",");
                    for (String s : split) {
                        SysUser sysUser = sysUserService.selectUserById(Long.parseLong(s));
                        if(sysUser == null){
                            throw new ServerException("用户ID为"+Long.parseLong(s)+"的审核人不存在");
                        }
                        assigneeNames.add(sysUser.getNickName());
                    }

                } catch (Exception e){
                    throw new ServerException("请配置下一节点审核人配置错误");
                }
                actBusinessFlowRel.setProcHandlerName(String.join(",",assigneeNames));
                actBusinessFlowRel.setTaskName(userTask.getName());
            }
        } else {
            // 如果没有下一个节点
            actBusinessFlowRel.setProcHandlerId("");
            actBusinessFlowRel.setProcHandlerName("");
            actBusinessFlowRel.setTaskName("");
            taskService.complete(currentTask.getId(), variabls);
            actBusinessFlowRel.setFlowState(2);
            // 更新关联业务 审批状态
            updateBusinessByType(actBusinessFlowRel,actBusinessFlowRel.getFlowState().toString());
        }
        // 给流程与业务关系历史节点审核人赋值
        if(StringUtils.isNotBlank(actBusinessFlowRel.getHisHandlerId())){
            actBusinessFlowRel.setHisHandlerId(actBusinessFlowRel.getHisHandlerId() + "," + loginUser.getUserId());
        } else {
            actBusinessFlowRel.setHisHandlerId(loginUser.getUserId().toString());
        }
        if(StringUtils.isNotBlank(actBusinessFlowRel.getHisHandlerName())){
            actBusinessFlowRel.setHisHandlerName(actBusinessFlowRel.getHisHandlerName() + "," + loginUser.getNickName());
        } else {
            actBusinessFlowRel.setHisHandlerName(loginUser.getNickName());
        }
        actBusinessFlowRelServiceImpl.updateById(actBusinessFlowRel);

        String procHandlerId = actBusinessFlowRel.getProcHandlerId();
        if(StringUtils.isNotBlank(procHandlerId)){
            String[] split = procHandlerId.split(",");
            for (String nextUserId : split) {
                // 发送消息
                sendPcMessage(nextUserId, flowApproveDto.getBussinessType(),flowApproveDto.getBussinessId());
            }
        } else {
            // 发送消息
            sendAppMessage(actBusinessFlowRel.getSendUserId(), flowApproveDto.getBussinessType(),flowApproveDto.getBussinessId(), "pass");
        }

    }

    private void sendPcMessage(String userId, String businessKey, Long bussinessId) throws ServerException {
        MessageInfo message = new MessageInfo();
        message.setUserId(Long.parseLong(userId));
        message.setCreateTime(new Date());
        message.setState("0");
        message.setEnable("0");
        message.setDeleted("0");
        message.setTitle("审批事项通知");
        switch (businessKey){
            case "XIEPAIHANBIAOSHI":
                AssociationClapCulvert byId = associationClapCulvertServiceImpl.getById(bussinessId);
                if(byId == null){
                    throw new ServerException("协拍函数据不存在");
                }
                if("1".equals(byId.getDeleted())){
                    throw new ServerException("协拍函数据已被删除");
                }
                message.setContent("有新的协拍函办理申请待你审批（协拍函编号："+byId.getXphNum()+"）");
                break;
            case "WCPATENT":
                WcPatentApplication wcPatentApplication = wcPatentApplicationServiceImpl.getById(bussinessId);
                if(wcPatentApplication == null){
                    throw new ServerException("剧本备案申请数据不存在");
                }
                if("1".equals(wcPatentApplication.getDeleted())){
                    throw new ServerException("剧本备案申请数据已被删除");
                }
                message.setContent("有新的剧本备案申请待你审批（影片名称："+wcPatentApplication.getMovieName()+"）");
                break;
            case "WCCHANGEPATENT":
                WcChangePatentApplication wcChangePatentApplication = wcChangePatentApplicationService.getById(bussinessId);
                if(wcChangePatentApplication == null){
                    throw new ServerException("剧本变更备案数据不存在");
                }
                if("1".equals(wcChangePatentApplication.getDeleted())){
                    throw new ServerException("剧本变更备案数据已被删除");
                }
                message.setContent("有新的剧本变更备案申请待你审批（影片名称："+wcChangePatentApplication.getMovieName()+"）");
                break;
            case "WCCONTENTEXAMINE":
                WcContentExamine wcContentExamine = wcContentExamineService.getById(bussinessId);
                if(wcContentExamine == null){
                    throw new ServerException("影片内容审查数据不存在");
                }
                if("1".equals(wcContentExamine.getDeleted())){
                    throw new ServerException("影片内容审查数据已被删除");
                }
                message.setContent("有新的影片审查待你审批（影片名称："+wcContentExamine.getMovieName()+"）");
                break;
            case "FYPROJECT":
                FyProjectApply fyProjectApply = fyProjectApplyService.getById(bussinessId);
                if(fyProjectApply == null){
                    throw new ServerException("扶垚计划项目申报数据不存在");
                }
                if("1".equals(fyProjectApply.getDeleted())){
                    throw new ServerException("扶垚计划项目申报数据已被删除");
                }
                message.setContent("有新的扶垚计划项目申报待你审批（项目名称："+fyProjectApply.getName()+"）");
                break;
            default: throw new ServerException("不存在的业务类型");
        }
//        messageInfoService.insertMessageInfo(message);
    }

    private void sendAppMessage(String userId, String businessKey, Long bussinessId, String status) throws ServerException {
        com.ruoyi.workflow.domain.Message message = new Message();
        message.setUserId(userId);
        message.setCreateTime(new Date());
        switch (businessKey){
            case "XIEPAIHANBIAOSHI":
                AssociationClapCulvert byId = associationClapCulvertServiceImpl.getById(bussinessId);
                if(byId == null){
                    throw new ServerException("协拍函数据不存在");
                }
                if("1".equals(byId.getDeleted())){
                    throw new ServerException("协拍函数据已被删除");
                }
                message.setMessageType(MessageType.CO_PRODUCTION_LETTER_RESULT_NOTIFICATION);
                message.setMessageContent("提交的协拍函办理申请已通过；影片名：" + byId.getXphNum());
                message.setDetailUrl("详情跳转路径");
                break;
            case "WCPATENT":
                WcPatentApplication wcPatentApplication = wcPatentApplicationServiceImpl.getById(bussinessId);
                if(wcPatentApplication == null){
                    throw new ServerException("剧本备案申请数据不存在");
                }
                if("1".equals(wcPatentApplication.getDeleted())){
                    throw new ServerException("剧本备案申请数据已被删除");
                }
                message.setMessageType(MessageType.SCRIPT_RECORDING_RESULT_NOTIFICATION);
                message.setMessageContent("提交的电影剧本（梗概）备案申请已通过；影片名：" + wcPatentApplication.getMovieName());
                message.setDetailUrl("详情跳转路径");
                break;
            case "WCCHANGEPATENT":
                WcChangePatentApplication wcChangePatentApplication = wcChangePatentApplicationService.getById(bussinessId);
                if(wcChangePatentApplication == null){
                    throw new ServerException("剧本变更备案数据不存在");
                }
                if("1".equals(wcChangePatentApplication.getDeleted())){
                    throw new ServerException("剧本变更备案数据已被删除");
                }
                message.setMessageType(MessageType.SCRIPT_CHANGE_RECORDING_RESULT_NOTIFICATION);
                message.setMessageContent("提交的电影剧本（梗概）变更备案申请已通过；影片名：" + wcChangePatentApplication.getMovieName());
                message.setDetailUrl("详情跳转路径");
                break;
            case "WCCONTENTEXAMINE":
                WcContentExamine wcContentExamine = wcContentExamineService.getById(bussinessId);
                if(wcContentExamine == null){
                    throw new ServerException("影片内容审查数据不存在");
                }
                if("1".equals(wcContentExamine.getDeleted())){
                    throw new ServerException("影片内容审查数据已被删除");
                }
                message.setMessageType(MessageType.DOMESTIC_MOVIE_REVIEW_RESULT_NOTIFICATION);
                message.setMessageContent("提交的国产电影内容审查申请已通过；影片名：" + wcContentExamine.getMovieName());
                message.setDetailUrl("详情跳转路径");
                break;
            case "FYPROJECT":
                FyProjectApply fyProjectApply = fyProjectApplyService.getById(bussinessId);
                if(fyProjectApply == null){
                    throw new ServerException("扶垚计划项目申报数据不存在");
                }
                if("1".equals(fyProjectApply.getDeleted())){
                    throw new ServerException("扶垚计划项目申报数据已被删除");
                }
                message.setMessageType(MessageType.FUYAO_PROJECT_APPLICATION_RESULT_NOTIFICATION);
                message.setMessageContent("提交的扶垚计划项目申报申请已通过；项目名：" + fyProjectApply.getName());
                message.setDetailUrl("详情跳转路径");
                break;
            default: throw new ServerException("不存在的业务类型");
        }
//        userMessageService.sendMessage(message);
    }

    private void updateBussiness(Long bussinessId,String bussinessType,String processInstanceId) throws ServerException {
        if(bussinessId == null){
            throw new ServerException("业务数据ID不能为空");
        }
        if(StringUtils.isBlank(bussinessType)){
            throw new ServerException("业务类型不能为空");
        }
        switch (bussinessType){
            case "XIEPAIHANBIAOSHI":
                AssociationClapCulvert byId = associationClapCulvertServiceImpl.getById(bussinessId);
                if(byId == null){
                    throw new ServerException("协拍函数据不存在");
                }
                if("1".equals(byId.getDeleted())){
                    throw new ServerException("协拍函数据已被删除");
                }
                byId.setFlowId(processInstanceId);
                associationClapCulvertServiceImpl.updateById(byId);
                break;
            case "WCPATENT":
                WcPatentApplication wcPatentApplication = wcPatentApplicationServiceImpl.getById(bussinessId);
                if(wcPatentApplication == null){
                    throw new ServerException("剧本备案申请数据不存在");
                }
                if("1".equals(wcPatentApplication.getDeleted())){
                    throw new ServerException("剧本备案申请数据已被删除");
                }
                wcPatentApplication.setFlowId(processInstanceId);
                wcPatentApplicationServiceImpl.updateById(wcPatentApplication);
                break;
            case "WCCHANGEPATENT":
                WcChangePatentApplication wcChangePatentApplication = wcChangePatentApplicationService.getById(bussinessId);
                if(wcChangePatentApplication == null){
                    throw new ServerException("剧本变更备案数据不存在");
                }
                if("1".equals(wcChangePatentApplication.getDeleted())){
                    throw new ServerException("剧本变更备案数据已被删除");
                }
                wcChangePatentApplication.setFlowId(processInstanceId);
                wcChangePatentApplicationService.updateById(wcChangePatentApplication);
                break;
            case "WCCONTENTEXAMINE":
                WcContentExamine wcContentExamine = wcContentExamineService.getById(bussinessId);
                if(wcContentExamine == null){
                    throw new ServerException("影片内容审查数据不存在");
                }
                if("1".equals(wcContentExamine.getDeleted())){
                    throw new ServerException("影片内容审查数据已被删除");
                }
                wcContentExamine.setFlowId(processInstanceId);
                wcContentExamineService.updateById(wcContentExamine);
                break;
            case "FYPROJECT":
                FyProjectApply fyProjectApply = fyProjectApplyService.getById(bussinessId);
                if(fyProjectApply == null){
                    throw new ServerException("扶垚计划项目申报数据不存在");
                }
                if("1".equals(fyProjectApply.getDeleted())){
                    throw new ServerException("扶垚计划项目申报数据已被删除");
                }
                fyProjectApply.setFlowId(processInstanceId);
                fyProjectApplyService.updateById(fyProjectApply);
                break;
            default: throw new ServerException("不存在的业务类型");
        }
    }



    @Override
    public List<UserTask> getNextTaskNode(String taskId, Integer isCountersign) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        org.activiti.bpmn.model.Process process = bpmnModel.getProcesses().get(0);
        // 获取所有普通任务节点
        List<FlowElement> UserTaskList = (List<FlowElement>) process.getFlowElements();
        Map<String, Object> flowElements = new HashMap<>();
        UserTaskList.stream().forEach(item -> {
            flowElements.put(item.getId(), item);
        });
        Object flowElement = flowElements.get(task.getTaskDefinitionKey());
        UserTask userTask = (UserTask) flowElement;
        List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
        if(CollectionUtils.isEmpty(outgoingFlows)){
            return null;
        }
        List<UserTask> nextUserTasks = new ArrayList<>();
        //构造参数

        for (SequenceFlow outgoingFlow : outgoingFlows) {
//            String conditionExpression = outgoingFlow.getConditionExpression();
//            if(StringUtils.isNotBlank(conditionExpression) && isCountersign != null){
//                //设置了分支流程并且携带了outcome参数
//                String stringByELAndFormData = "false";
//                Map<String, String> map = new HashMap<>();
//                map.put("isCountersign", isCountersign.toString());
//                try {
//                    //验证outcome参数是否符合表达式
//                    stringByELAndFormData = (String) getStringByELAndFormData(conditionExpression, map);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//                if("false".equals(stringByELAndFormData)){
//                    continue;
//                }
//            }
//            // 获取出线连接的目标节点
//            String nextId = outgoingFlow.getTargetRef();
//            UserTask res = (UserTask)flowElements.get(nextId);
//            nextUserTasks.add(res);
            if(outgoingFlow.getTargetFlowElement() instanceof ExclusiveGateway){
                ExclusiveGateway targetFlowElement = (ExclusiveGateway)outgoingFlow.getTargetFlowElement();
                List<SequenceFlow> exclusiveGatewayOutgoingFlows = targetFlowElement.getOutgoingFlows();
                for (SequenceFlow exclusiveGatewayOutgoingFlow : exclusiveGatewayOutgoingFlows) {
                    String conditionExpression = exclusiveGatewayOutgoingFlow.getConditionExpression();
                    if(StringUtils.isNotBlank(conditionExpression) && isCountersign != null){
                        Map<String, String> map = new HashMap<>();
                        map.put("countersign", isCountersign.toString());
                        //设置了分支流程并且携带了outcome参数
                        String stringByELAndFormData = "false";
                        try {
                            //验证outcome参数是否符合表达式
                            stringByELAndFormData = (String) getStringByELAndFormData(conditionExpression, map);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if("false".equals(stringByELAndFormData)){
                            continue;
                        }
                        // 获取出线连接的目标节点
                        String nextId = exclusiveGatewayOutgoingFlow.getTargetRef();
                        UserTask res = (UserTask)flowElements.get(nextId);
                        nextUserTasks.add(res);
                    }
                }
            } else if(outgoingFlow.getTargetFlowElement() instanceof UserTask){
                UserTask targetFlowElement = (UserTask)outgoingFlow.getTargetFlowElement();
                nextUserTasks.add(targetFlowElement);
            }
        }

//        for (UserTask userTask : UserTaskList) {
//            // 获取当前任务节点Id
//            String id = userTask.getId();
//            if (id.equals(task.getTaskDefinitionKey())) {
//                List<UserTask> nextUserTasks = new ArrayList<>();
//                //构造参数
//                Map<String, String> map = new HashMap<>();
//                map.put("outcome",outcome);
//                // 获取当前任务节点的所有出线信息
//                List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
//                for (SequenceFlow sequenceFlow : outgoingFlows) {
//                    //设置了分支流程并且携带了outcome参数
//                    if(StringUtils.isNotEmpty(sequenceFlow.getConditionExpression()) && StringUtils.isNotEmpty(outcome)){
//                        String stringByELAndFormData = "false";
//                        try {
//                            //验证outcome参数是否符合表达式
//                            stringByELAndFormData = (String) getStringByELAndFormData(sequenceFlow.getConditionExpression(), map);
//                        } catch (Exception e) {
//                            e.printStackTrace();
//                        }
//                        if("false".equals(stringByELAndFormData)){
//                            continue;
//                        }
//                    }
//
//                    // 获取出线连接的目标节点
//                    String nextId = sequenceFlow.getTargetRef();
//                    // 获取到了下一个节点的Id
////                    String nextId = targetFlowElement.getId();
////                    String nextId = "";
//                    List<UserTask> UserTaskLists = process.findFlowElementsOfType(UserTask.class);
//                    // 再次遍历所有普通任务节点
//                    for (UserTask nextUserTask : UserTaskLists) {
//                        // 获取任务节点Id
//                        String flowId = nextUserTask.getId();
//                        // 如果遍历的某个任务节点Id等于下一个节点的Id
//                        if (flowId.equals(nextId)) {
//                            nextUserTasks.add(nextUserTask);
//                        }
//                    }
//                }
//                return nextUserTasks;
//            }
//        }
        return nextUserTasks;
    }

    @Override
    public List<UserTask> getNextTaskNodeByActivityId(String businessId) throws ServerException {
        LoginUser user = SecurityUtils.getLoginUser();
        SysUser loginUser = user.getUser();
        Task task = taskService.createTaskQuery().taskAssignee(loginUser.getUserId().toString()).processInstanceId(businessId).singleResult();
        if(task == null){
            throw new ServerException("当前登录人不是审核员或节点不存在");
        }
        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        org.activiti.bpmn.model.Process process = bpmnModel.getProcesses().get(0);
        // 获取所有普通任务节点
        List<FlowElement> UserTaskList = (List<FlowElement>) process.getFlowElements();
        Map<String, Object> flowElements = new HashMap<>();
        UserTaskList.stream().forEach(item -> {
            flowElements.put(item.getId(), item);
        });
        Object flowElement = flowElements.get(task.getTaskDefinitionKey());
        UserTask userTask = (UserTask) flowElement;
        List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
        if(CollectionUtils.isEmpty(outgoingFlows)){
            return null;
        }
        List<UserTask> nextUserTasks = new ArrayList<>();
        //构造参数
        for (SequenceFlow outgoingFlow : outgoingFlows) {
            if(outgoingFlow.getTargetFlowElement() instanceof ExclusiveGateway){
                ExclusiveGateway targetFlowElement = (ExclusiveGateway)outgoingFlow.getTargetFlowElement();
                List<SequenceFlow> exclusiveGatewayOutgoingFlows = targetFlowElement.getOutgoingFlows();
                for (SequenceFlow exclusiveGatewayOutgoingFlow : exclusiveGatewayOutgoingFlows) {
                    // 获取出线连接的目标节点
                    String nextId = exclusiveGatewayOutgoingFlow.getTargetRef();
                    UserTask res = (UserTask)flowElements.get(nextId);
                    nextUserTasks.add(res);
                }
            } else if(outgoingFlow.getTargetFlowElement() instanceof UserTask){
                UserTask targetFlowElement = (UserTask)outgoingFlow.getTargetFlowElement();
                nextUserTasks.add(targetFlowElement);
            }
        }

        return nextUserTasks;
    }

    @Override
    public UserTask currentNodeByFlowId(String flowId) throws ServerException {
        LoginUser user = SecurityUtils.getLoginUser();
        SysUser loginUser = user.getUser();
        Task task = taskService.createTaskQuery().taskAssignee(loginUser.getUserId().toString()).processInstanceId(flowId).singleResult();
        if(task == null){
            throw new ServerException("当前登录人不是审核员或节点不存在");
        }
        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        org.activiti.bpmn.model.Process process = bpmnModel.getProcesses().get(0);
        // 获取所有普通任务节点
        List<FlowElement> UserTaskList = (List<FlowElement>) process.getFlowElements();
        Map<String, Object> flowElements = new HashMap<>();
        UserTaskList.stream().forEach(item -> {
            flowElements.put(item.getId(), item);
        });
        Object flowElement = flowElements.get(task.getTaskDefinitionKey());
        UserTask userTask = (UserTask) flowElement;
        return userTask;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void endProcess(FlowApproveDto flowApproveDto) throws Exception {
        LoginUser user = SecurityUtils.getLoginUser();
        SysUser loginUser = user.getUser();
        Task currentTask = taskService.createTaskQuery().taskAssignee(loginUser.getUserId().toString()).processInstanceId(flowApproveDto.getFlowId()).singleResult();
        FlowElement endActivity = findLastOneActiviti(currentTask.getId(),flowApproveDto.getFlowId());
        String description = currentTask.getDescription();
        if(StringUtils.isBlank(description)){
            throw new ServerException("流程配置错误");
        }

        DescriptionInfo descriptionInfo = JSON.parseObject(description, DescriptionInfo.class);
        descriptionInfo.setRemarks("审核驳回：" + flowApproveDto.getDescription());
        if(flowApproveDto.getStats() == 6){
            descriptionInfo.setApprovalStatus("不同意");
        } else if(flowApproveDto.getStats() == 5){
            descriptionInfo.setApprovalStatus("修改后同意");
        } else {
            descriptionInfo.setApprovalStatus("退回");
        }

        descriptionInfo.setApprovalFileIds(flowApproveDto.getApprovalFileUrls());
//        String overruledToActivityId = descriptionInfo.getOverruledToActivityId();
//        FlowElement endActivity = findLastOneActiviti(currentTask.getId(),overruledToActivityId);
        commitProcess(currentTask.getId(), null, endActivity, JSON.toJSONString(descriptionInfo));
        // 驳回后修改数据审核状态
        ActBusinessFlowRel actBusinessFlowRel = actBusinessFlowRelServiceImpl.getOne(new LambdaQueryWrapper<ActBusinessFlowRel>()
                .eq(ActBusinessFlowRel::getBusinessId, flowApproveDto.getBussinessId())
                .eq(ActBusinessFlowRel::getBusinessType, flowApproveDto.getBussinessType()));
        if(actBusinessFlowRel == null){
            throw new ServerException("业务数据与流程关系不存在");
        }
        // 给流程与业务关系历史节点审核人赋值
        if(StringUtils.isNotBlank(actBusinessFlowRel.getHisHandlerId())){
            actBusinessFlowRel.setHisHandlerId(actBusinessFlowRel.getHisHandlerId() + "," + loginUser.getUserId());
        } else {
            actBusinessFlowRel.setHisHandlerId(loginUser.getUserId().toString());
        }
        if(StringUtils.isNotBlank(actBusinessFlowRel.getHisHandlerName())){
            actBusinessFlowRel.setHisHandlerName(actBusinessFlowRel.getHisHandlerName() + "," + loginUser.getNickName());
        } else {
            actBusinessFlowRel.setHisHandlerName(loginUser.getNickName());
        }

        if(endActivity instanceof UserTask){
            UserTask userTask = (UserTask) endActivity;
            actBusinessFlowRel.setProcHandlerId(userTask.getAssignee());
            if(StringUtils.isNotBlank(userTask.getAssignee())){
                SysUser sysUser = sysUserService.selectUserById(Long.parseLong(userTask.getAssignee()));
                if (sysUser != null) {
                    actBusinessFlowRel.setProcHandlerName(sysUser.getNickName());
                } else {
                    actBusinessFlowRel.setProcHandlerName("");
                }
            }
            actBusinessFlowRel.setTaskName(userTask.getName());
            // 发送消息
            sendPcMessage(userTask.getAssignee(), flowApproveDto.getBussinessType(), flowApproveDto.getBussinessId());
        }
        if(endActivity instanceof EndEvent){
            actBusinessFlowRel.setProcHandlerId("");
            actBusinessFlowRel.setProcHandlerName("");
            actBusinessFlowRel.setFlowState(flowApproveDto.getStats());
            actBusinessFlowRel.setTaskName("");
            // 发送消息
            sendAppMessage(actBusinessFlowRel.getSendUserId(), flowApproveDto.getBussinessType(),flowApproveDto.getBussinessId(), "refuse");
        }
        actBusinessFlowRelServiceImpl.updateById(actBusinessFlowRel);
        // 更新关联业务 审批状态
        updateBusinessByType(actBusinessFlowRel,flowApproveDto.getStats().toString());
    }


    @Override
    public TableDataInfo getlist(String key, String name, Boolean latest, Integer pageSize, Integer pageNum) {

        ProcessDefinitionQuery queryCondition = repositoryService.createProcessDefinitionQuery();
        if (com.ruoyi.common.utils.StringUtils.isNotEmpty(key)) {
            queryCondition.processDefinitionKey(key);
        }
        if (com.ruoyi.common.utils.StringUtils.isNotEmpty(name)) {
            queryCondition.processDefinitionName(name);
        }
        if (latest) {
            queryCondition.latestVersion();
        }
        int total = queryCondition.list().size();
        int start = (pageNum - 1) * pageSize;
        List<ProcessDefinition> pageList = queryCondition.orderByDeploymentId().desc().listPage(start, pageSize);
        List<Process> mylist = new ArrayList<Process>();
        for (int i = 0; i < pageList.size(); i++) {
            Process p = new Process();
            p.setDeploymentId(pageList.get(i).getDeploymentId());
            p.setId(pageList.get(i).getId());
            p.setKey(pageList.get(i).getKey());
            p.setName(pageList.get(i).getName());
            p.setResourceName(pageList.get(i).getResourceName());
            p.setDiagramresourceName(pageList.get(i).getDiagramResourceName());
            p.setVersion(pageList.get(i).getVersion());
            p.setSuspended(pageList.get(i).isSuspended());
            mylist.add(p);
        }
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(0);
        rspData.setRows(mylist);
        rspData.setTotal(total);
        return rspData;
    }

    @Override
    public void showresource(String pdid, HttpServletResponse response) throws IOException {
        BpmnModel bpmnModel = repositoryService.getBpmnModel(pdid);
        ProcessDiagramGenerator diagramGenerator = new DefaultProcessDiagramGenerator();
        InputStream is = diagramGenerator.generateDiagram(bpmnModel, "png",  "宋体", "宋体", "宋体", configuration.getClassLoader(), 1.0);
        ServletOutputStream output = response.getOutputStream();
        IOUtils.copy(is, output);
    }

    @Override
    public void getPictiue(String pdid, String flowId) throws Exception {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        HistoryService historyService = processEngine.getHistoryService();

        BpmnModel model = repositoryService.getBpmnModel(flowId);

        ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();

        //lastTask是当前任务执行到的位置
        List<HistoricActivityInstance> lastTasks =
                historyService.createHistoricActivityInstanceQuery()
                        // 指定流程实例id-processInstanceId
                        .processInstanceId(pdid)
                        // 按时间降序排序
                        .orderByHistoricActivityInstanceStartTime()
                        .desc()
                        .list();

        // 拿到最后1个时间执行的活动实例id
        List<String> lastTask = lastTasks.stream()
                .map(HistoricActivityInstance::getActivityId)
                .limit(1)
                .collect(Collectors.toList());

        lastTask.add(lastTasks.get(0).getActivityId());

        //七个参数分别是：
        //  BPMNModel
        //  高光节点
        //  高光顺序流
        //  活动字体名称
        //  标签字体名称
        //  批注字体名称
        //  生成默认关系图
        //  默认关系图映像文件名
//        InputStream inputStream = generator.generateDiagram(model,lastTask, new ArrayList<String>(), "宋体","宋体","宋体",true,"test");
//        List<String> highLightedActivities = processEngine.getRuntimeService().getActiveActivityIds(processInstance.getId());// 高亮节点
        List<String> highLightedFlows = new ArrayList<>(); // 高亮连接线
        ProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
        InputStream inputStream = processDiagramGenerator.generateDiagram(model, "png", lastTask, highLightedFlows, "宋体", "宋体", "宋体", null, 1.0);

        String imageName = "image-" + Instant.now().getEpochSecond() + ".png";
        FileUtils.copyInputStreamToFile(inputStream, new File("process/" + imageName));

    }

    @Override
    public byte[] getProcessInstanceImage(String instanceId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
        String processDefinitionId = StringUtils.EMPTY;
        if (processInstance == null) {
            // 查询已经结束的流程实例
            HistoricProcessInstance processInstanceHistory = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(instanceId).singleResult();
            if (processInstanceHistory == null) {
                return null;
            } else {
                processDefinitionId = processInstanceHistory.getProcessDefinitionId();
            }
        } else {
            processDefinitionId = processInstance.getProcessDefinitionId();
        }

        // 使用宋体
        String fontName = "宋体";

        // 获取BPMN模型对象
        BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);

        // 获取历史流程实例
        // 获取流程中已经执行的节点，按照执行先后顺序排序
        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId).orderByHistoricActivityInstanceId().asc().list();

        ProcessDiagramGenerator dg = new DefaultProcessDiagramGenerator();
//        ProcessDiagramGenerator dg = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();

        /**高亮所有已执行的节点和线条
         // 高亮已经执行流程节点ID集合
         List<String> highLightedActivitiIds = new ArrayList<>();
         for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
         highLightedActivitiIds.add(historicActivityInstance.getActivityId());
         }

         // 高亮线路id集合
         List<String> highLightedFlows = getHighLightedFlows(model, historicActivityInstances);


         InputStream stream = dg.generateDiagram(model, "png", highLightedActivitiIds, highLightedFlows, fontName,fontName, fontName, null, 1.0);
         */

        /**高亮当前待执行节点*/
        // 获取流程实例当前的节点，需要高亮显示
        List<String> currentActs = Collections.emptyList();
        if (processInstance != null) {
            currentActs = runtimeService.getActiveActivityIds(processInstance.getId());
        }
        InputStream stream = dg.generateDiagram(model, "png", currentActs, new ArrayList<String>(), fontName,fontName, fontName, null, 1.0);
        try {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024 * 4];
            int n = 0;
            while (-1 != (n = stream.read(buffer))) {
                output.write(buffer, 0, n);
            }
            return output.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                stream.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

    @Override
    public void withdraw(Long businessId) throws ServerException {
        if(businessId == null){
            throw new ServerException("业务数据ID不能为空");
        }
        ActBusinessFlowRel actBusinessFlowRel = actBusinessFlowRelServiceImpl.getOne(new LambdaQueryWrapper<ActBusinessFlowRel>()
                .eq(ActBusinessFlowRel::getBusinessId, businessId));
        if(actBusinessFlowRel == null){
            throw new ServerException("业务数据与流程关系不存在");
        }
        if(StringUtils.isNotBlank(actBusinessFlowRel.getHisHandlerId())){
            throw new ServerException("当前节点" + actBusinessFlowRel.getTaskName() + "不允许撤回");
        }

        actBusinessFlowRelServiceImpl.update(new LambdaUpdateWrapper<ActBusinessFlowRel>()
                .eq(ActBusinessFlowRel::getProcRelId, actBusinessFlowRel.getProcRelId())
                .set(ActBusinessFlowRel::getFlowState, 4)
                .set(ActBusinessFlowRel::getProcHandlerId, null)
                .set(ActBusinessFlowRel::getProcHandlerName, null));
        updateBusinessByType(actBusinessFlowRel,"4");
    }



    private String getStringByELAndFormData(String el, Map formData) throws Exception {

        ExpressionFactory factory = new ExpressionFactoryImpl();
        SimpleContext context = new SimpleContext();
        for (Object k : formData.keySet()) {
            if (formData.get(k) != null) {
                context.setVariable(k.toString(),
                        factory.createValueExpression(formData.get(k), formData.get(k).getClass()));
            }
        }

        ValueExpression e = factory.createValueExpression(context, el, String.class);
        return (String) e.getValue(context);
    }

    /**
     * 根据任务ID和节点ID获取活动节点 <br>
     *
     * @param taskId     任务ID
     * @param activityId 活动节点ID <br>
     *                   如果为null或""，则默认查询当前活动节点 <br>
     *                   如果为"end"，则查询结束节点 <br>
     *
     * @return
     * @throws Exception
     */
    private FlowElement findActivitiImpl(String taskId, String activityId) throws Exception {
        // 获取当前活动节点ID
        if (StringUtils.isEmpty(activityId)) {
            activityId = actTaskService.findTaskById(taskId).getTaskDefinitionKey();
        }

        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        org.activiti.bpmn.model.Process process = bpmnModel.getProcesses().get(0);
        Collection<FlowElement> flowElements = process.getFlowElements();
        for (FlowElement flowElement : flowElements) {
            if (activityId.toUpperCase().equals("END") && flowElement instanceof EndEvent) {
                return flowElement;
            } else if (flowElement.getId().equals(activityId)) {
                return flowElement;
            }
        }
        return null;

    }

    /**
     * 获取上一个审批过的节点
     * @param taskId
     * @param activity
     * @return
     * @throws Exception
     */
    private FlowElement findLastOneActiviti(String taskId, String activity) throws Exception {
        // 获取当前活动节点ID
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
//        String taskDefinitionKey = task.getTaskDefinitionKey();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        org.activiti.bpmn.model.Process process = bpmnModel.getProcesses().get(0);
//        List<UserTask> userTaskLists = process.findFlowElementsOfType(UserTask.class);
//        Map<String, Object> userTaskMap = new HashMap<>();
//        for (UserTask userTask : userTaskLists) {
//            if(userTask.getId().equals(activity)){
//                return userTask;
//            }
////            userTaskMap.put(userTaskList.getId(), userTaskList);
//        }
//        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).orderByHistoricTaskInstanceEndTime().desc().finished().list();
//        for (HistoricTaskInstance historicTaskInstance : list) {
//            if(!historicTaskInstance.getTaskDefinitionKey().equals(taskDefinitionKey)){
//                Object currentUserTaskObj = userTaskMap.get(historicTaskInstance.getTaskDefinitionKey());
//                return (UserTask) currentUserTaskObj;
//            }
//        }

        // 如果没有获取到上一节点就返回结束节点
        List<EndEvent> endEvent = process.findFlowElementsOfType(EndEvent.class);
        return endEvent.get(0);
    }

    /**
     * @param taskId     当前任务ID
     * @param variables  流程变量
     *                   此参数为空，默认为提交操作
     * @throws Exception
     */
    private void commitProcess(String taskId, Map<String, Object> variables, FlowElement flowElement, String description)
            throws Exception {
        if (variables == null) {
            variables = new HashMap<String, Object>();
        }
//        if (StringUtils.isEmpty(activityId)) {
//            // 跳转节点为空，默认提交操作
//            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
//
//            if(task.getDelegationState()!=null && task.getDelegationState().equals(DelegationState.PENDING)) {
//                taskService.resolveTask(taskId,variables);
//            }
//
//            task.setDescription(description);
//            taskService.saveTask(task);
//            taskService.complete(taskId, variables);
//        } else {
//            turnTransition(taskId, variables, description, activityId);
//        }
        turnTransition(taskId, variables, description, flowElement);
    }

    /**
     * 	流程跳转
     * @Title: turnTransition
     * @Description: TODO(这里用一句话描述这个方法的作用)
     * @param @param taskId
     * @param @param variables
     * @param @param description
     * @param @param targetNodeElementIds
     * @return void
     * @throws
     */
    private void turnTransition(String taskId,Map<String,Object> variables,String description,FlowElement flowElement) {
        Task myTask = taskService.createTaskQuery().taskId(taskId).singleResult();

        String processDefinitionId = myTask.getProcessDefinitionId();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);

        Execution sourceExecution = runtimeService.createExecutionQuery().executionId(myTask.getExecutionId()).singleResult();

        FlowNode sourceFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sourceExecution.getActivityId());

        // 记录原活动方向
        List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
        oriSequenceFlows.addAll(sourceFlowNode.getOutgoingFlows());

        // 清理活动方向
        sourceFlowNode.getOutgoingFlows().clear();

        org.activiti.bpmn.model.Process process =bpmnModel.getMainProcess();

        //获取目标节点定义
        List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
        FlowNode targetFlowNode = (FlowNode) process.getFlowElement(flowElement.getId());
        SequenceFlow newSequenceFlow = new SequenceFlow();
        newSequenceFlow.setId("newSequenceFlowId" + UUID.randomUUID());
        newSequenceFlow.setSourceFlowElement(sourceFlowNode);
        newSequenceFlow.setTargetFlowElement(targetFlowNode);
        newSequenceFlowList.add(newSequenceFlow);
        sourceFlowNode.setOutgoingFlows(newSequenceFlowList);


//			Authentication.setAuthenticatedUserId(userId);
        taskService.addComment(myTask.getId(), myTask.getProcessInstanceId(), description);

        myTask.setDescription(description);
        taskService.saveTask(myTask);

        // 完成任务
        taskService.complete(myTask.getId(), variables);

        //如果跳转后的节点有人处理过，则恢复到指定处理人
//        List<Task> nextTasks = taskService.createTaskQuery().processInstanceId(myTask.getProcessInstanceId()).active().list();
//        for (Task task : nextTasks) {
//            Execution taskExecution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
//            task.setAssignee(targetNodeAssignees.get(taskExecution.getActivityId()));
//            taskService.saveTask(task);
//        }

        // 恢复原方向
        sourceFlowNode.setOutgoingFlows(oriSequenceFlows);
    }


    /**
     * 更新关联业务 审批状态
     * @param status--审批状态( 0审批中 1审批通过 2审批驳回)
     */
    private void updateBusinessByType(ActBusinessFlowRel actBusinessFlowRel,String status) {

        if(BusinessFlag.FY_PROJECT.getValue().equals(actBusinessFlowRel.getBusinessType())){
            UpdateWrapper<FyProjectApply> wrapper = new UpdateWrapper<>();
            wrapper.set("status",status).eq("id", actBusinessFlowRel.getBusinessId());
            fyProjectApplyService.update(wrapper);
        }
        if(BusinessFlag.WC_CONTENT_EXAMINE.getValue().equals(actBusinessFlowRel.getBusinessType())){
            UpdateWrapper<WcContentExamine> wrapper = new UpdateWrapper<>();
            wrapper.set("status",status).eq("id", actBusinessFlowRel.getBusinessId());
            wcContentExamineService.update(wrapper);
        }
        if(BusinessFlag.WC_CHANGE_PATENT.getValue().equals(actBusinessFlowRel.getBusinessType())){
            UpdateWrapper<WcChangePatentApplication> wrapper = new UpdateWrapper<>();
            wrapper.set("status",status).eq("id", actBusinessFlowRel.getBusinessId());
            wcChangePatentApplicationService.update(wrapper);
        }
        if(BusinessFlag.WC_PATENT.getValue().equals(actBusinessFlowRel.getBusinessType())){
            UpdateWrapper<WcPatentApplication> wrapper = new UpdateWrapper<>();
            wrapper.set("status",status).eq("id", actBusinessFlowRel.getBusinessId());
            wcPatentApplicationService.update(wrapper);
        }
    }
}
